#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdbool.h>


#define BUF_SIZE 1024
void error_handling( char *msg);

bool is_operator(int ch);


int main(int argc, char *argv[])
{   
    int sock;
    char msg[BUF_SIZE];
    int str_len;
    struct sockaddr_in serv_adr;

    if ( argc != 3) {
        printf("Usage: %s <IP> <port>\n", argv[0]);
        exit(1);
    }

    sock = socket(PF_INET, SOCK_STREAM, 0);
    if (-1 == sock) {
        error_handling("socket() error");
    }

    memset(&serv_adr, 0, sizeof(serv_adr));
    serv_adr.sin_family = AF_INET;
    serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
    serv_adr.sin_port   = htons(atoi(argv[2]));

    if ( -1 == connect(sock, 
        (struct sockaddr *)&serv_adr, sizeof(serv_adr))) {
        error_handling("connect() error!");
    }
    else {
        puts("Connected.......");
    }

    while (1) {

        fputs("operate number cnt:  ", stdout);
        int num_cnt;
        scanf("%d", &num_cnt);
        
        if (-1 == write(sock, &num_cnt, sizeof(num_cnt))) {
            error_handling("write() op_cnt error!");
        }

        for (int i = 0; i < num_cnt; ++i) {
            int num;

            scanf("%d", &num);
            printf("%dth number is: %d\n", i + 1, num);
            if ( -1 ==   write(sock, &num, sizeof(num))) {
                error_handling("write number error!");
            }
        }

        fflush(stdin);
        int op_ch;
        
        scanf(" %c", &op_ch);
        while ( !is_operator(op_ch)) {
            printf("invalid operator: %c!\n", op_ch);
            printf("try again!");

            scanf(" %c", &op_ch);
        }
        printf("get op: %c\n", op_ch);

        if (-1 == write(sock, &op_ch, sizeof(op_ch))) {
            error_handling("write operator error!");
        }
        printf("wait for result return...\n");

        int res;

        if ( -1 == read(sock, &res, sizeof(res))) {
            error_handling("read result failed");
        }
        else {
            printf("result is: %d\n", res);
        }
        break;
    }
    close(sock);


    return 0;
}

void error_handling(char *msg)
{
    fputs(msg, stderr);
    fputc('\n', stderr);
    exit(1);
}

bool is_operator(int ch) {

    const char *s_op = "+-*/";
    int len = strlen(s_op);
    int i = 0;
    
    for (int i = 0;i < len; ++i) {
        if ( s_op[i] == ch )
            return true;
    }

    return false;
}
